package org.NooLab.browserapp.components;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import org.NooLab.browserapp.app.BrousProperties;
import org.NooLab.itexx.comm.tcp.box.TcpBox;

import org.NooLab.structures.infra.remotely.ActionRequest;
import org.NooLab.utilities.files.DFutils;
import org.NooLab.utilities.files.PathFinder;
import org.NooLab.utilities.files.StopFileWatcher;
import org.NooLab.utilities.logging.PrintLog;
import org.NooLab.utilities.strings.StringsUtil;





public class BrowserFactory implements Observer{

	public BrowserMain browser;
	
	TcpBox tcpBox;
	BrousProperties brProperties;
	
	
	PrintLog out = new PrintLog(2,false);
	StringsUtil strgutil = new StringsUtil();
	DFutils fileutil = new DFutils();

	ArrayList<ActionRequest> requestedActions = new ArrayList<ActionRequest>();
	Actions actions;

	private StopFileWatcher stopper;

	private boolean closing=false;
	
	
	// ========================================================================
	public BrowserFactory(BrousProperties brProperties){
		this.brProperties = brProperties;
		
		actions = new Actions(this) ;
		browser = new BrowserMain(this) ;
	}
	// ========================================================================
	
	
	public static BrowserFactory get(BrousProperties lpProperties) {
		// 
		BrowserFactory factory = new BrowserFactory(lpProperties);
		return factory;
	}

	public void close() {
		// 
		
		tcpBox.getTcpReceiver().closePort() ;
		
		browser.close();
		
		closing=true;
		out.delay(200);
		out.printErr(1, "NNB received a request to stop, now exiting (code:8)...");
		System.exit(8) ;
	}



	public TcpBox getTcpBox() {
		return tcpBox ; 
	}
	public void setTcpBox(TcpBox tcpBox) {
		// 
		this.tcpBox = tcpBox;
	}

	public void saveStartupTrace(String nlpFlavor, String traceInfo) {
		// 
		String userdir, cfgTraceFile;
		
		if (brProperties.isITexxContext()){
			userdir = DFutils.createPath( brProperties.getSystemRootDir(),"bin/");
		}else{ 
			userdir = fileutil.getUserDir(); // ???
		}
		
		cfgTraceFile = fileutil.createpath(userdir, "noonlp-.startup") ;
		
		
		fileutil.writeFileSimple(cfgTraceFile,traceInfo); 
		
	}

	public void go() {
		// 
		
		// setting TCP out, wrapped by observers through
		
		try {
			
			browser.perform();
			
			establishStoppingFile();
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}


	private void establishStoppingFile() throws Exception{
		String sfile ;

		sfile = (new PathFinder()).getAppBinPath(this.getClass(), true);
		if (sfile.indexOf(".jar")>0){
			sfile = StringsUtil.getLastPartOfString( sfile, "/") ;
		}else{
			sfile = PathFinder.getMainClassName() ; // this does not work: System.getenv("JAVA_MAIN_CLASS");
			if(sfile.length()==0){
				sfile = "NooLabNativeBrowserApp.jar";
			}
		}
		
		String ext = StringsUtil.getExtensionFromFilename(sfile);
		sfile = sfile.replace(ext, "")+".stop";

		String path = brProperties.getApplicationHomeDir() ;
		
		stopper = new StopFileWatcher( (Observer)this, path, sfile, false, 500);
		
		out.print(2, "StopFileWatcher is observing file <"+stopper.getObservedFile()+">");
		
		int z=0; 
		while ((z<500) && (stopper.isObserving()==false)){
			out.delay(2);	z++;
		}
		if (stopper.isObserving()==false){
			out.print(1, "No stop file observer available!");
		}

	}
	

	@Override
	public void update(Observable sendObj, Object msgObj) {
		// 
		
		String senderName = sendObj.getClass().getSimpleName();
		// we send it back 
		out.print(1, "msg from <"+(sendObj.getClass().getSimpleName())+">");
		out.print(1, " ... received by BrowserFactory : "+((String) msgObj)) ;
		if ((senderName.contains("StopFile")) && ((String) msgObj).contains("StopFile")){
			close();
			out.delay(300);
			out.printErr(2, "BrowserApplication has been shut down.\n");
			System.exit(8);
		}
		
	}


	public void handlingActionRequests(ActionRequest obj) {

		ActionRequest arq = (ActionRequest)obj;
		String cmd;
		
		cmd = arq.getCmdFamily().toLowerCase();
		if ((cmd==null) || (cmd.length()==0)){
			out.print(2, "received command was empty, thus nothing will be done.");
			return;
		}
		if (cmd.contentEquals("close")){
			actions.setClosingScheduled(true) ;
			
			if (arq.getCmdDetail().toLowerCase().contains("immediate")){
				close();
			}
		}
		requestedActions.add( arq ); 
	}


	public void checkForClosing(int sentResultsCount, int receivedStringsCount) {
		// 
		if (sentResultsCount == receivedStringsCount){
			// 
			close();
		}
	}


	public boolean isClosing() {
		// 
		return closing;
	}
	
	
}

